package com.example.demo.suanfa;

/* ━━━━━━佛祖保佑━━━━━━
 *                  ,;,,;
 *                ,;;'(    社
 *      __      ,;;' ' \   会
 *   /'  '\'~~'~' \ /'\.)  主
 * ,;(      )    /  |.     义
 *,;' \    /-.,,(   ) \    码
 *     ) /       ) / )|    农
 *     ||        ||  \)
 *     (_\       (_\
 * ━━━━━━永无BUG━━━━━━
 * @author ：zjq
 * @date ：2021/4/26 15:53
 * @description: TODO           漏桶限流算法   用于 sentinel 排队等待
 * @version: V1.0
 * @slogan: 天下风云出我辈，一入代码岁月催
 */
public class LeakyBucket {

    public long timeStamp = System.currentTimeMillis();  // 当前时间
    public long capacity; // 桶的容量
    public long rate; // 水漏出的速度(每秒系统能处理的请求数)
    public long water; // 当前水量(当前累积请求数)

    public boolean limit() {
        long now = System.currentTimeMillis();
        long currentRate = ((now - timeStamp) / 1000) *rate;
        //  先执行漏水，计算剩余水量  如果流出的过快，则把当前水量设为 0
        water = Math.max(0, water - currentRate);
        timeStamp = now;
        //  water+1  表示 当前水量(当前累积请求数)+一个新来一个请求 <  桶的容量
        System.out.println("water:   "+water);
        if ((water + 1) < capacity) {
            // 尝试加水,并且水还未满 每次来的 请求数
            water += 10;
            return true;
        } else {
            // 水满，拒绝加水   所以这里就不会  water += 10;
            return false;
        }
    }

    public static void main(String[] args) throws InterruptedException {

        LeakyBucket a = new LeakyBucket();
        a.capacity = 100;
        a.rate = 2;
        a.water = 0;
        while (true) {
            Thread.sleep(1001);
            boolean limit = a.limit();
            if (limit) {
                System.out.println("没有限流");
            } else {
                System.out.println("限流");
            }


        }

    }

}
